package org.jeecg.modules.rental.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.rental.vo.LoginRentalAccount;
import org.jeecg.modules.iot.cache.EBikeCache;
import org.jeecg.modules.iot.model.Location;
import org.jeecg.modules.iot.model.power.TaiPower;
import org.jeecg.modules.rental.entity.RentalAccount;
import org.jeecg.modules.rental.entity.RentalAccountEBike;
import org.jeecg.modules.rental.entity.RentalEBike;
import org.jeecg.modules.rental.entity.RentalEbikeShare;
import org.jeecg.modules.rental.mapper.RentalAccountEBikeMapper;
import org.jeecg.modules.rental.mapper.RentalAccountMapper;
import org.jeecg.modules.rental.mapper.RentalEBikeMapper;
import org.jeecg.modules.rental.mapper.RentalEbikeShareMapper;
import org.jeecg.modules.rental.resp.EBikeShareResp;
import org.jeecg.modules.rental.resp.ShareAcountResp;
import org.jeecg.modules.rental.resp.ShareEBikeResp;
import org.jeecg.modules.rental.service.IRentalEbikeShareService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 控制分享
 * @Author: sean
 * @Date:   2024-12-19
 * @Version: V1.0
 */
@Service
@RequiredArgsConstructor
public class RentalEbikeShareServiceImpl extends ServiceImpl<RentalEbikeShareMapper, RentalEbikeShare> implements IRentalEbikeShareService {

    private final RentalAccountMapper rentalAccountMapper;
    private final RentalEBikeMapper rentalEBikeMapper;
    private final RentalAccountEBikeMapper rentalAccountEBikeMapper;
    private final EBikeCache eBikeCache;

    @Override
    public List<ShareAcountResp> shareList(Long ebikeId) {
        List<RentalEbikeShare> shareList = baseMapper
                .selectList(new QueryWrapper<RentalEbikeShare>().eq("ebike_id", ebikeId));
        List<ShareAcountResp> list = new ArrayList<>();
        if(ObjectUtil.isNotEmpty(shareList)){
            List<Long> accountIds = shareList.stream()
                    .map(RentalEbikeShare::getAccountId).collect(Collectors.toList());
            List<RentalAccount> accountList = rentalAccountMapper.selectBatchIds(accountIds);
            shareList.forEach(item->{
                ShareAcountResp shareAcountResp = new ShareAcountResp();
                shareAcountResp.setIsCtrl(item.getIsCtrl());
                shareAcountResp.setValue(item.getId().toString());
                Optional<RentalAccount> accountOptional = accountList.stream().filter(a-> a.getId().equals(item.getAccountId())).findFirst();
                accountOptional.ifPresent(a-> shareAcountResp.setName(StrUtil.isNotBlank(a.getAccountName()) ? a.getAccountName() : a.getAccountCode()));
                accountOptional.ifPresent(a-> shareAcountResp.setDisabled(a.getId().equals(item.getOwnerId())));
                list.add(shareAcountResp);
            });
        }
        return list;
    }

    @Override
    public Boolean addShereAccount(Long ebikeId, String accountCode) {
        RentalAccount account = rentalAccountMapper
                .selectOne(new QueryWrapper<RentalAccount>()
                        .and(wq -> wq.eq("account_code", accountCode).or().eq("email", accountCode).or().eq("phone", accountCode)));
        RentalAccountEBike accountEBike = rentalAccountEBikeMapper
                .selectOne(new QueryWrapper<RentalAccountEBike>().eq("ebike_id", ebikeId));
        if(ObjectUtil.isNotEmpty(account) && ObjectUtil.isNotEmpty(accountEBike)){
            RentalEbikeShare ebikeShare = new RentalEbikeShare();
            ebikeShare.setEbikeId(ebikeId);
            ebikeShare.setAccountId(account.getId());
            ebikeShare.setOwnerId(accountEBike.getAccountId());
            ebikeShare.setIsCtrl(Boolean.FALSE);
            return baseMapper.insert(ebikeShare) > 0;
        }
        return false;
    }

    @Override
    public Boolean removeShereAccount(String ids) {
        List<String> idList = Arrays.asList(ids.split(","));
        return baseMapper.deleteBatchIds(idList) > 0;
    }

    @Override
    public Boolean removeShereAccount(Long id) {
        return baseMapper.deleteById(id) > 0;
    }

    @Override
    public Boolean setCtrlStatus(Long id, Boolean isCtrl) {
        RentalEbikeShare ebikeShare = baseMapper.selectById(id);
        if(ObjectUtil.isNotEmpty(ebikeShare)){
            if(isCtrl){
                //如果要设置成占用 需要将其他人占用该车辆的状态去掉
                List<RentalEbikeShare> ebikeShareList = baseMapper
                        .selectList(new QueryWrapper<RentalEbikeShare>()
                                .eq("ebike_id", ebikeShare.getEbikeId())
                                .eq("is_ctrl", Boolean.TRUE));
                ebikeShareList.forEach(item->{
                    item.setIsCtrl(Boolean.FALSE);
                });
                this.updateBatchById(ebikeShareList);
                //如果要设置成占用,要求只能占用一辆车子，所以也要把该用户的其他占用车子状态给去掉
                List<RentalEbikeShare> ebikeShareList2 = baseMapper
                        .selectList(new QueryWrapper<RentalEbikeShare>()
                                .eq("account_id", ebikeShare.getAccountId())
                                .eq("is_ctrl", Boolean.TRUE));
                ebikeShareList2.forEach(item->{
                    item.setIsCtrl(Boolean.FALSE);
                });
                this.updateBatchById(ebikeShareList2);
            }
            ebikeShare.setIsCtrl(isCtrl);
            return baseMapper.updateById(ebikeShare) > 0;
        }
        return false;
    }


    @Override
    public Boolean setCtrlEBike(Long ebikeId) {
        List<RentalEbikeShare> existEBikes = baseMapper.selectList(new QueryWrapper<RentalEbikeShare>()
                .eq("ebike_id", ebikeId)
                .eq("is_ctrl", Boolean.TRUE));
        if(ObjectUtil.isNotEmpty(existEBikes)){
            throw new JeecgBootException("rentalcarpackage.service.car.already.used");
        }
        LoginRentalAccount rentalAccount = (LoginRentalAccount) SecurityUtils.getSubject().getPrincipal();
        RentalEbikeShare ebikeShare = baseMapper
                .selectOne(new QueryWrapper<RentalEbikeShare>()
                        .eq("ebike_id", ebikeId)
                        .eq("account_id", rentalAccount.getId()));
        ebikeShare.setIsCtrl(Boolean.TRUE);
        return baseMapper.updateById(ebikeShare) > 0;
    }

    @Override
    public Boolean setEndCtrl(Long ebikeId) {
        LoginRentalAccount rentalAccount = (LoginRentalAccount) SecurityUtils.getSubject().getPrincipal();
        RentalEbikeShare existEBike = baseMapper.selectOne(new QueryWrapper<RentalEbikeShare>()
                .eq("account_id", rentalAccount.getId())
                .eq("ebike_id", ebikeId));
        if(ObjectUtil.isNotEmpty(existEBike)){
            existEBike.setIsCtrl(Boolean.FALSE);
            return baseMapper.updateById(existEBike) > 0;
        }
        return Boolean.FALSE;
    }

    @Override
    public List<EBikeShareResp> shareAccountList(Long ebikeId) {
        List<RentalEbikeShare> shareList = baseMapper
                .selectList(new QueryWrapper<RentalEbikeShare>().eq("ebike_id", ebikeId));
        List<EBikeShareResp> list = new ArrayList<>();
        if(ObjectUtil.isNotEmpty(shareList)){
            List<Long> accountIds = shareList.stream()
                    .map(RentalEbikeShare::getAccountId).collect(Collectors.toList());
            List<RentalAccount> accountList = rentalAccountMapper.selectBatchIds(accountIds);
            shareList.forEach(item->{
                EBikeShareResp eBikeShareResp = new EBikeShareResp();
                BeanUtils.copyProperties(item, eBikeShareResp);
                Optional<RentalAccount> accountOptional = accountList.stream().filter(a-> a.getId().equals(item.getAccountId())).findFirst();
                accountOptional.ifPresent(a-> eBikeShareResp.setAccountName(StrUtil.isNotBlank(a.getAccountName()) ? a.getAccountName() : a.getAccountCode()));
                accountOptional.ifPresent(a-> eBikeShareResp.setIsOwner(a.getId().equals(item.getOwnerId())));
                list.add(eBikeShareResp);
            });
        }
        return list;
    }

    @Override
    public List<ShareEBikeResp> ebikeList() {
        LoginRentalAccount rentalAccount = (LoginRentalAccount) SecurityUtils.getSubject().getPrincipal();
        List<RentalEbikeShare> ebikeShareList = baseMapper
                .selectList(new QueryWrapper<RentalEbikeShare>()
                        .eq("account_id", rentalAccount.getId()));
        List<ShareEBikeResp> eBikeList = new ArrayList<>();
        if(ObjectUtil.isNotEmpty(ebikeShareList)){
            Set<Long> ebikeIdList = ebikeShareList.stream()
                    .map(RentalEbikeShare::getEbikeId).collect(Collectors.toSet());
            List<RentalEBike> rentalEbikeList = rentalEBikeMapper.selectBatchIds(ebikeIdList);

            List<RentalEbikeShare> ctrlList = baseMapper
                    .selectList(new QueryWrapper<RentalEbikeShare>()
                            .in("ebike_id", ebikeIdList)
                            .eq("is_ctrl", Boolean.TRUE));
            rentalEbikeList.forEach(item->{
                ShareEBikeResp eBikeResp = new ShareEBikeResp();
                eBikeResp.setEbikeId(item.getId()); //电单车id
                eBikeResp.setEbikePlate(item.getPlate()); //电单车车辆
                eBikeResp.setEbikeCode(item.getCarCode());
                eBikeResp.setEbikeCustomCode(StrUtil.isNotBlank(item.getCustomCode())?item.getCustomCode():item.getCarCode()); //电单车自编号
                TaiPower taiPower = eBikeCache.getVehiclePower(item.getCarCode());
                if(ObjectUtil.isNotEmpty(taiPower)){
                    eBikeResp.setEbikePower(taiPower.getRPowCap()); //电单车在线状态
                }
                eBikeResp.setOnlineStatus(eBikeCache.getVehicleOnlineStatus(item.getCarCode())); //电单车在线状态
                Location location = eBikeCache.getVehicleLocation(item.getCarCode());
                if(ObjectUtil.isNotEmpty(location)){
                    eBikeResp.setLatitude(location.getLatitude());
                    eBikeResp.setLongitude(location.getLongitude());
                }
                if(ObjectUtil.isNotEmpty(ctrlList)){
                    Optional<RentalEbikeShare> ebikeShareOptional = ctrlList.stream()
                            .filter(a-> a.getEbikeId().equals(item.getId())).findFirst();
                    Set<Long> accountIds =  ctrlList.stream()
                            .map(RentalEbikeShare::getAccountId).collect(Collectors.toSet());
                    List<RentalAccount> rentalAccountList = rentalAccountMapper
                            .selectBatchIds(accountIds);
                    ebikeShareOptional.ifPresent(a->{
                        Optional<RentalAccount> accountOptional = rentalAccountList.stream()
                                .filter(b -> b.getId().equals(a.getAccountId()))
                                .findFirst();
                        accountOptional.ifPresent(b-> eBikeResp.setCtrlAccount(StrUtil.isNotBlank(b.getAccountName()) ? b.getAccountName() : b.getAccountCode())); //占用电单车账户
                        eBikeResp.setCtrlStatus(Boolean.TRUE); //电单车占用状态
                        if(a.getAccountId().equals(rentalAccount.getId())){
                            eBikeResp.setIsCtrl(Boolean.TRUE); //电单车是否是我占用
                        }
                    });
                }else{
                    eBikeResp.setCtrlAccount(null);
                    eBikeResp.setCtrlStatus(Boolean.FALSE); //电单车占用状态
                    eBikeResp.setIsCtrl(Boolean.FALSE); //电单车是否是我占用
                }
                eBikeList.add(eBikeResp);
            });
        }
        return eBikeList;
    }

}
